package com.s59.rabc.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.s59.rabc.commen.LoginException;
import com.s59.rabc.commen.LoginUser;
import com.s59.rabc.commen.Token;
import com.s59.rabc.entity.Menu;
import com.s59.rabc.entity.Role;
import com.s59.rabc.entity.User;
import com.s59.rabc.mapper.UserMapper;
import com.s59.rabc.redis.RedisUtils;
import com.s59.rabc.security.UserDetailsimpl;
import com.s59.rabc.service.ILoginService;
import com.s59.rabc.service.IMenuService;
import com.s59.rabc.service.IRoleService;
import com.s59.rabc.entity.vo.LoginVo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sun.plugin.liveconnect.SecurityContextHelper;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.s59.rabc.commen.Constants.CACHE_PREFIX_TOKEN;

@Service
public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements ILoginService {
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PermssionService permssionService;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    @SneakyThrows
    public Token login(LoginVo loginVo) throws LoginException {
        User user = getBaseMapper().selectOne(Wrappers.lambdaQuery(User.class).eq(User::getUserName,loginVo.getUsername()));
        if(user == null){
            throw new LoginException("用户不存在");
        }
        if(!loginVo.getPassword().equals(user.getPassword())){
            throw new LoginException("密码不正确");
        }
        String uuid = UUID.randomUUID().toString();
        cacheLoginUser(user,uuid);
        Token token = new Token();
        token.setToken(uuid);
        return token;
    }

    private void cacheLoginUser(User user,String uuid) throws JsonProcessingException {
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(user.getUserName());
        loginUser.setNickname(user.getNickName());
        loginUser.setPermsList(permssionService.getParms(user.getUserName()));
        loginUser.setRoleKeyList(permssionService.getRoleKey(user.getUserName()));
        redisUtils.set(CACHE_PREFIX_TOKEN+uuid,new ObjectMapper().writeValueAsString(loginUser),1800);
    }


    @Override
    public void logout(String token) {
        redisUtils.del(CACHE_PREFIX_TOKEN+token);
    }

    @SneakyThrows
    @Override
    public Token ssLogin(LoginVo loginVo) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(),loginVo.getPassword());
        //自动调用UsernamePasswordAuthenticationToken
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        UserDetailsimpl userDetailsimpl = (UserDetailsimpl) authenticate.getPrincipal();
        String uuid = UUID.randomUUID().toString();
        redisUtils.set(CACHE_PREFIX_TOKEN+uuid,new ObjectMapper().writeValueAsString(userDetailsimpl),1800);
        Token token = new Token();
        token.setToken(uuid);
        return token;
    }
}
